package com.woniuxy.broker;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.woniuxy.enums.Exchange;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.HashMap;
import java.util.Map;


/**
 * @author bootystar
 */
@SpringBootApplication
@MapperScan("com.woniuxy.broker.mapper")
@EnableDiscoveryClient
@EnableSwagger2
@Slf4j
public class BrokerApplication {

    public static void main(String[] args) {
        SpringApplication.run(BrokerApplication.class, args);
    }


    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //分页拦截器paginationInnerInterceptor
        final PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        //设置数据库的类型
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        //如果用户传入的page大于实际page，返回第一页的数据
        paginationInnerInterceptor.setOverflow(true);
        //设置每一页的最大条数
        paginationInnerInterceptor.setMaxLimit(100L);
        //封装
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);

        return mybatisPlusInterceptor;
    }


    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .pathMapping("/")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.woniuxy.broker.controller"))
                .paths(PathSelectors.any())
                .build().apiInfo(new ApiInfoBuilder()
                        .title("接口文档")
                        .description("经纪人模块接口文档")
                        .version("9.0")
                        .contact(new Contact("booty", "http://www.baidu.com", "bootystar@163.com"))
                        .license("The Apache License")
                        .licenseUrl("http://www.baidu.com")
                        .build());
    }


    @Bean
    public Queue queue() {
        return new Queue(Exchange.BROKER_EXCHANGE.getQuery(), true, false, false);
    }

    @Bean
    DirectExchange directExchange() {
        return new DirectExchange(Exchange.BROKER_EXCHANGE.getName(), true, false);
    }

    @Bean
    Binding bindingDirect() {
        return BindingBuilder.bind(queue()).to(directExchange()).with(Exchange.BROKER_EXCHANGE.getRouterKey());
    }


    @Bean
    public Queue delayQueue() {
        Map<String, Object> args = new HashMap<>(2);
        args.put("x-message-ttl", 10000);
        args.put("x-dead-letter-exchange", Exchange.BROKER_EXCHANGE_DEAD.getName());
        return new Queue(Exchange.BROKER_EXCHANGE_DELAY.getQuery(), true, false, false, args);
    }

    @Bean
    DirectExchange delayDirectExchange() {
        return new DirectExchange(Exchange.BROKER_EXCHANGE_DELAY.getName(), true, false);
    }

    @Bean
    Binding delayBindingDirect() {
        return BindingBuilder.bind(delayQueue()).to(delayDirectExchange()).with(Exchange.BROKER_EXCHANGE_DELAY.getRouterKey());
    }


    @Bean
    public Queue deadQueue() {
        return new Queue(Exchange.BROKER_EXCHANGE_DEAD.getQuery(), true, false, false);
    }

    @Bean
    DirectExchange deadDirectExchange() {
        return new DirectExchange(Exchange.BROKER_EXCHANGE_DEAD.getName(), true, false);
    }

    @Bean
    Binding deadBindingDirect() {
        return BindingBuilder.bind(deadQueue()).to(deadDirectExchange()).with(Exchange.BROKER_EXCHANGE_DEAD.getRouterKey());
    }


    @Bean
    RabbitTemplate.ReturnCallback returnCallback() {
        return (message, replyCode, replyText, exchangeName, routingKey) -> log.info("returnedMessage 回调信息 ===> replyCode={} ,replyText={} ,exchangeName={} ,routingKey={}", replyCode, replyText, exchangeName, routingKey);
    }

    @Bean
    RabbitTemplate.ConfirmCallback confirmCallback() {
        return (correlationData, isSuccess, callbackReason) -> {
            if (!isSuccess) {
                log.info("消息发送异常！模拟会发送异常执行的业务逻辑");
                //此处可编写实际业务逻辑
            } else {
                log.info("发送者已经收到确认，correlationData(消息id)={} , cause={}", correlationData.getId(), callbackReason);
            }
        };
    }

//    private static final String NORMAL_QUEUE = Exchange.BROKER_EXCHANGE.getQuery();
//    private static final String DELAY_QUEUE = Exchange.BROKER_EXCHANGE_DELAY.getQuery();
//    private static final String DEAD_QUEUE = Exchange.BROKER_EXCHANGE_DEAD.getQuery();


}
